#include <iostream>
#include <memory> // 为了使用智能指针

using namespace std;
void pre_b2cc(){
    // 使用智能指针自动管理资源
    unique_ptr<TChain> chain(new TChain("BJpsiPi0Tuple/DecayTree")); 
    chain->Add("/afs/cern.ch/user/j/jiankang/eosl/Mc_down/B0JpsiPi0_md.root"); 

    Bool_t B_L0MuonDecision_TOS;
    Bool_t B_L0DiMuonDecision_TOS;
    Bool_t B_Hlt1DiMuonLowMassDecision_TOS;
    Bool_t B_Hlt1DiMuonHighMassDecision_TOS;
    Bool_t B_Hlt1TrackMuonDecision_TOS;
    Bool_t B_Hlt1SingleMuonHighPTDecision_TOS;
    Bool_t B_Hlt2DiMuonDetachedJPsiDecision_TOS;

    Double_t gamma0_PT; // gamma0的动量
    Double_t gamma0_CaloHypo_isNotH; // gamma0是否不是Hypo的标志
    Double_t gamma1_PT; // gamma1的动量
    Double_t gamma1_CaloHypo_isNotH; // gamma1是否不是Hypo的标志
    Double_t pi0_PT; // pi0的解析动量
    Double_t pi0_M; // pi0的质量
    Double_t B_M; // B_M的值
    Double_t B_IP_OWNPV; //IP与源初顶点  
    Double_t B_IPCHI2_OWNPV; //IP与源初顶点的 Chi2值
    Double_t B_DIRA_OWNPV; //粒子在衰变中方向角的参数
   
    Double_t B_ENDVERTEX_CHI2; //末态顶点拟合的Chi2值
    Double_t B_OWNPV_CHI2; //源初顶点拟合的Chi2值
    Int_t B_ENDVERTEX_NDOF; // 末态顶点的自由度
    Int_t B_OWNPV_NDOF; // 源初顶点的自由度

    Int_t gamma0_TRUEID; // gamma0的真正ID
    Int_t gamma1_TRUEID; // gamma1的真正ID
    Int_t gamma0_MC_MOTHER_ID; // gamma0的MC母亲ID
    Int_t gamma1_MC_MOTHER_ID; // gamma1的MC母亲ID
    Int_t gamma0_MC_MOTHER_KEY; // gamma0的MC母亲键
    Int_t gamma1_MC_MOTHER_KEY; // gamma1的MC母亲键
    Int_t mu1_TRUEID; // 正mu子的真正ID
    Int_t mu2_TRUEID; // 负mu子的真正ID
    Int_t mu1_MC_MOTHER_ID; // 正mu子的MC母亲ID
    Int_t mu2_MC_MOTHER_ID; // 负mu子的MC母亲ID
    Int_t mu1_MC_MOTHER_KEY; // 正mu子的MC母亲键
    Int_t mu2_MC_MOTHER_KEY; // 负mu子的MC母亲键
    Int_t mu1_MC_GD_MOTHER_ID; // 正mu子的MC通用母亲ID
    Int_t mu2_MC_GD_MOTHER_ID; // 负mu子的MC通用母亲ID
    Int_t gamma0_MC_GD_MOTHER_ID; // gamma0的MC通用母亲ID
    Int_t gamma1_MC_GD_MOTHER_ID; // gamma1的MC通用母亲ID   


    chain->SetBranchAddress("B_L0MuonDecision_TOS",                 &B_L0MuonDecision_TOS);
    chain->SetBranchAddress("B_L0DiMuonDecision_TOS",               &B_L0DiMuonDecision_TOS);
    chain->SetBranchAddress("B_Hlt1DiMuonLowMassDecision_TOS", &B_Hlt1DiMuonLowMassDecision_TOS);
    chain->SetBranchAddress("B_Hlt1DiMuonHighMassDecision_TOS",     &B_Hlt1DiMuonHighMassDecision_TOS);
    chain->SetBranchAddress("B_Hlt1TrackMuonDecision_TOS",          &B_Hlt1TrackMuonDecision_TOS);
    chain->SetBranchAddress("B_Hlt1SingleMuonHighPTDecision_TOS",   &B_Hlt1SingleMuonHighPTDecision_TOS);
    chain->SetBranchAddress("B_Hlt2DiMuonDetachedJPsiDecision_TOS", &B_Hlt2DiMuonDetachedJPsiDecision_TOS);
    chain->SetBranchAddress("gamma0_PT",                            &gamma0_PT);
    chain->SetBranchAddress("gamma0_CaloHypo_isNotH",               &gamma0_CaloHypo_isNotH);
    chain->SetBranchAddress("gamma1_PT",                            &gamma1_PT);
    chain->SetBranchAddress("gamma1_CaloHypo_isNotH",               &gamma1_CaloHypo_isNotH);
    chain->SetBranchAddress("pi0_PT",                               &pi0_PT);
    chain->SetBranchAddress("pi0_M",                                &pi0_M);
    chain->SetBranchAddress("gamma0_TRUEID",                        &gamma0_TRUEID);
    chain->SetBranchAddress("gamma1_TRUEID",                        &gamma1_TRUEID);
    chain->SetBranchAddress("gamma0_MC_MOTHER_ID",                  &gamma0_MC_MOTHER_ID);
    chain->SetBranchAddress("gamma1_MC_MOTHER_ID",                  &gamma1_MC_MOTHER_ID);
    chain->SetBranchAddress("gamma0_MC_MOTHER_KEY",                 &gamma0_MC_MOTHER_KEY);
    chain->SetBranchAddress("gamma1_MC_MOTHER_KEY",                 &gamma1_MC_MOTHER_KEY);
    chain->SetBranchAddress("mu1_TRUEID",                           &mu1_TRUEID);
    chain->SetBranchAddress("mu2_TRUEID",                           &mu2_TRUEID); 
    chain->SetBranchAddress("mu1_MC_MOTHER_ID",                     &mu1_MC_MOTHER_ID);
    chain->SetBranchAddress("mu2_MC_MOTHER_ID",                     &mu2_MC_MOTHER_ID);
    chain->SetBranchAddress("mu1_MC_GD_MOTHER_ID",                  &mu1_MC_GD_MOTHER_ID);
    chain->SetBranchAddress("mu2_MC_GD_MOTHER_ID",                  &mu2_MC_GD_MOTHER_ID);
    chain->SetBranchAddress("mu2_MC_MOTHER_KEY",                    &mu2_MC_MOTHER_KEY);
    chain->SetBranchAddress("mu1_MC_MOTHER_KEY",                    &mu1_MC_MOTHER_KEY);
    chain->SetBranchAddress("gamma0_MC_GD_MOTHER_ID",               &gamma0_MC_GD_MOTHER_ID);
    chain->SetBranchAddress("gamma1_MC_GD_MOTHER_ID",               &gamma1_MC_GD_MOTHER_ID);
    chain->SetBranchAddress("B_M",                                  &B_M);
    chain->SetBranchAddress("B_IP_OWNPV",                           &B_IP_OWNPV);
    chain->SetBranchAddress("B_IPCHI2_OWNPV",                       &B_IPCHI2_OWNPV);
    chain->SetBranchAddress("B_DIRA_OWNPV",                         &B_DIRA_OWNPV);
    chain->SetBranchAddress("B_ENDVERTEX_CHI2",                     &B_ENDVERTEX_CHI2);
    chain->SetBranchAddress("B_ENDVERTEX_NDOF",                     &B_ENDVERTEX_NDOF);
    chain->SetBranchAddress("B_OWNPV_CHI2",                         &B_OWNPV_CHI2);
    chain->SetBranchAddress("B_OWNPV_NDOF",                         &B_OWNPV_NDOF);

    // 使用 try-catch 捕获可能的异常
    unique_ptr<TFile> newfile;
    try {
        newfile.reset(new TFile("/afs/cern.ch/user/j/jiankang/jiankang/pre/mc-down/pre_b2cc.root","RECREATE"));
    } catch (const exception& e) {
       cerr << "Failed to open or create new root file: " << e.what() << endl;
        return; // 早期退出以避免进一步错误
    }

    unique_ptr<TTree> newtree(chain->CloneTree(0));

    Long64_t nevent = chain->GetEntries();  //获得事件的总数
    Long64_t Ndis = nevent / 25, ab = 0,  abcd = 0;     //Ndis:Number of distributions事件的分布
    int counters[17] = {0}; // 由于只有5个分支被计数，调整数组大小为6。定义一个大小为6的整数型数组，并将其所有元素初始化为0

    for(Long64_t i = 0; i < nevent; ++i){
        if(i % Ndis == 0){  //如果i能被Ndis整除，则输出>到标准输出，并刷新缓冲区
            cout << ">" << flush;
        }
        ab++;

        try {
            chain->GetEntry(i); //确保正确读取每个事例
        } catch (const exception& e) {
            cerr << "Error getting entry " << i << ": " << e.what() << endl;
            continue; // 跳过当前事件以避免错误扩散
        }

    //CUT 即一系列的粒子筛选条件
        if(!(abs(mu1_TRUEID)==13 && abs(mu1_MC_MOTHER_ID)==443 && abs(mu1_MC_GD_MOTHER_ID)==511 &&
            abs(mu2_TRUEID)==13 && abs(mu2_MC_MOTHER_ID)==443 && abs(mu2_MC_GD_MOTHER_ID)==511 &&
            mu1_MC_MOTHER_KEY==mu2_MC_MOTHER_KEY &&
            abs(gamma0_TRUEID)==22 && abs(gamma0_MC_MOTHER_ID)==111 && abs(gamma0_MC_GD_MOTHER_ID)==511 &&
            abs(gamma1_TRUEID)==22 && abs(gamma1_MC_MOTHER_ID)==111 && abs(gamma1_MC_GD_MOTHER_ID)==511 &&
            gamma1_MC_MOTHER_KEY==gamma0_MC_MOTHER_KEY)) continue;
        counters[0]++;
        if(!(B_M < 7000)) continue;
        counters[1]++;
        if(!(B_M > 4800)) continue;
        counters[2]++;
        if(!(B_IP_OWNPV < 0.2)) continue;
        counters[3]++;
        if(!(B_IPCHI2_OWNPV < 20)) continue;
        counters[4]++;
        if(!(B_DIRA_OWNPV > 0.9995)) continue;
        counters[5]++;
        if(!((B_ENDVERTEX_CHI2 / B_ENDVERTEX_NDOF) < 10)) continue;
        counters[6]++;
        if(!((B_OWNPV_CHI2 / B_OWNPV_NDOF) < 10)) continue;
        counters[7]++;
        if(!(pi0_PT > 1000)) continue;
        counters[8]++;  
        if(!(pi0_M <= 300 && pi0_M > 0)) continue;
        counters[9]++;
        if(!(gamma0_PT > 200)) continue;
        counters[10]++;
        if(!(gamma0_CaloHypo_isNotH > 0.05)) continue;
        counters[11]++;
        if(!(gamma1_PT > 200)) continue;
        counters[12]++;
        if(!(gamma1_CaloHypo_isNotH > 0.05)) continue;
        counters[13]++;

        if (!((B_L0MuonDecision_TOS == 0)||(B_L0DiMuonDecision_TOS == 0))) continue;
        counters[14]++;
        if (!((B_Hlt1DiMuonLowMassDecision_TOS == 0)||(B_Hlt1DiMuonHighMassDecision_TOS == 0)||(B_Hlt1TrackMuonDecision_TOS == 0)||(B_Hlt1SingleMuonHighPTDecision_TOS == 0))) continue;
        counters[15]++;
        if (!(B_Hlt2DiMuonDetachedJPsiDecision_TOS == 1)) continue;
        counters[16]++;
        newtree->Fill();
        abcd++;
    }
    cout <<"\nEvents = " << ab  << ", Events(cut) = " << abcd << endl;
    cout <<"TrueIDs = " << counters[0] << endl;
    cout <<"B0_M = " << counters[2] << endl;
    cout <<"IPs = " << counters[3] << endl;
    cout <<"IPChi2s = " << counters[4] << endl;
    cout <<"DIRAs = " << counters[5] << endl;
    cout <<"ECN = " << counters[6] << endl;
    cout <<"OCN = " << counters[7] << endl;
    cout <<"PTs = " << counters[8] << endl;
    cout <<"Pi0_M = " << counters[9] << endl;
    cout <<"gam_PT = " << counters[10] << endl;
    cout <<"CaloHypos = " << counters[11] << endl;
    cout <<"gam_PT = " << counters[12] << endl;
    cout <<"CaloHypos = " << counters[13] << endl;
   

    newtree->Write();
    newfile->Close();
}



